#ifndef __WEBPAGE_PREPROCESSOR_H__
#define __WEBPAGE_PREPROCESSOR_H__

#include "Configuration.hpp"
#include "SplitTool.hpp"
#include "tinyxml2.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <regex>
#include <map>
#include <set>
#include <dirent.h>


using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::ofstream;
using std::regex;
using std::map;
using std::unordered_map;
using std::set;
using std::pair;
using WordSegmentation = se::SplitToolCppJieba;

namespace se
{

class WebPage
{
    friend bool operator==(const WebPage & lhs, const WebPage & rhs);//判断两文档是否相等
    friend bool operator<(const WebPage & lhs, const WebPage & rhs);//对文档按docId进行排序

public:
    /**
     * @brief 
     * @param doc 获取文档名
     * @param config 获取配置文件路径
     * @param jieba 分词工具
     */
    /* WebPage(string & doc, Configuration & config, SplitTool & jieba);//构造函数 */
    WebPage(string & doc);//构造函数

    /**
     * @brief 获取文档的docId
     * @return int 返回文档Id
     */
    int getDocId();
    
    /**
     * @breif 获取文档
     * @return string 返回文档名
     */
    string getTitle();
    
    /**
     * @brief 推荐词
     * @param queryWords 要查询的单词
     * @return string 若搜素内容过多，只显示前10条；不足10条则显示搜素到的内容
     */
    string getLink();
    string getDestription();

    string summary(const vector<string> & queryWords);
    
    /**
     * @brief 获取文档的词频统计map
     * @return map<string, int> 返回词频文件
     */ 
    map<string,int> & getWordsMap();
    
    /**
     * @brief 获取文档的词频统计map
     * @param doc 要处理的文档
     * @param config 配置文件
     * @param splitTool 分词方法
     * @return void
     */
    /* void processDoc(const string & doc, Configuration & config, SplitTool & splitTool);//对格式化文档进行处理 */
    void processDoc(const string & doc);//对格式化文档进行处理
    
    /**
     * @brief 求取文档的topk 词集
     * @param vordVec 词频文件
     * @param k topK
     * @param stopWorList 停用词
     * @return void
     */ 
    void calTopK(vector<string> & wordVec, int k, set<string> & stopWordList);//求取文档的topk词集


private:
    string _doc;//整篇文档，包含xml在内
    int _docId;//文档id
    string _docTitle;//文档标题
    string _docLink;//文档Link
    string _docDescription;//文档内容
    string _docSummary;//文档摘要，需自动生成，不是固定的
    vector<string> _topWords;//词频最高的前20个词
    map<string,int> _wordsMap;//保存每篇文档的所有词语和词频
    const static int TOPK_NUMBER = 20;
};

class PageLibPreprocessor
{
public:
    PageLibPreprocessor(Configuration & conf);//构造函数
    void doProcess();//执行预处理
    void readInfoFromFile();//根据配置信息读取网页库和位置偏移库的内容
    void cutRedundantPages();//对冗余的网页进行去重
    void buildInvertIndexTable();//创建倒排索引表
    void storeOnDisk();//将经过预处理之后的网页库、位置偏移库和倒排索引表写回到磁盘上
    void storeOnDisk_2();//将经过去重之后的网页库、位置偏移库和倒排索引表写回到磁盘上

private:
    std::pair<int,int> _pos;//偏移信息
    WordSegmentation _jieba;//分词对象
    vector<WebPage> _pageLib;//网页库的容器对象
    unordered_map<int, pair<int, int>> _offsetLib;//网页偏移库对象
    unordered_map<string, vector<pair<int, double>>> _invertIndexTable;//倒排索引表对象
    std::vector<std::pair<std::string,double>> _res;//关键词序列
};

}//end of namespace se

#endif

